﻿///<copyright>
/// Copyright © 2009 Stephen Styrchak. All Rights Reserved.
///</copyright>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ferpect.ComponentModel
{
    public class ScreenCollection : System.Collections.ObjectModel.KeyedCollection<string, IScreen>
    {
        private IGameLoop gameState;
        private IScreenManager owner;

        public ScreenCollection(IScreenManager owner)
        {
            if (owner == null) throw new ArgumentNullException("owner");
            this.owner = owner;
        }

        public void Initialize()
        {
            if (this.owner.Site == null)
            {
                throw new InvalidOperationException("ScreenCollection.Initialize must be called after the IScreenManager owner is sited.");
            }
            this.gameState = (IGameLoop)this.owner.Site.GetService(typeof(IGameLoop));
            if (gameState == null)
            {
                throw new InvalidOperationException("ScreenCollection.Initialize was not able to obtain an IGameLoop service from the owner's site.");
            }
            foreach (IScreen screen in this)
            {
                this.gameState.AddComponent(screen);
            }
        }

        private void OnScreenDisposed(object sender, EventArgs args)
        {
            IScreen screen = (IScreen)sender;
            screen.Disposed -= this.OnScreenDisposed;

            this.Remove(screen);
        }

        protected override void InsertItem(int index, IScreen screen)
        {
            if (this.gameState != null)
            {
                this.gameState.AddComponent(screen);
            }
            base.InsertItem(index, screen);
            screen.Disposed += this.OnScreenDisposed;
        }

        protected override void RemoveItem(int index)
        {
            if (index < 0 || index >= this.Count)
            {
                throw new IndexOutOfRangeException();
            }
            IScreen screen = this[index];
            base.RemoveItem(index);
            screen.Disposed -= this.OnScreenDisposed;
            if (this.gameState != null)
            {
                this.gameState.RemoveComponent(screen);
            }
        }

        protected override string GetKeyForItem(IScreen screen)
        {
            if (screen == null) throw new ArgumentNullException("screen");

            return screen.Name;
        }
    }
}
